package puan.com.weighBox;

import android.app.Service;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothManager;
import android.content.Context;
import android.content.Intent;
import android.os.Binder;
import android.os.Build;
import android.os.Handler;
import android.os.IBinder;
import android.util.Log;
import android.widget.Toast;

import com.evan.ble.BleManager;
import com.evan.ble.callback.BleGattCallback;
import com.evan.ble.callback.BleNotifyCallback;
import com.evan.ble.callback.BleScanCallback;
import com.evan.ble.callback.BleWriteCallback;
import com.evan.ble.data.BleDevice;
import com.evan.ble.data.BleScanState;
import com.evan.ble.exception.BleException;
import com.evan.ble.scan.BleScanRuleConfig;

import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;

import java.io.UnsupportedEncodingException;
import java.util.List;

import androidx.annotation.RequiresApi;
import puan.com.weighBox.bean.OrderBean;
import puan.com.weighBox.util.ByteUtils;
import puan.com.weighBox.util.Utils;

public class BluetoothService extends Service {

    private BluetoothAdapter bluetoothAdapter;


    private Handler handler = new Handler();
    private long SCAN_PERIOD = 5000;
    private boolean isHexSend = false;


    @Override
    public void onCreate() {
        super.onCreate();
        BluetoothManager bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
        bluetoothAdapter = bluetoothManager.getAdapter();

        EventBus.getDefault().register(this);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        EventBus.getDefault().unregister(this);
    }

    @Override
    public IBinder onBind(Intent intent) {
        return mBinder;
    }

    private IBinder mBinder = new MyBinder();

    public class MyBinder extends Binder {
        BluetoothService getService() {
            // Return this instance of LocalService so clients can call public methods
            return BluetoothService.this;
        }

    }


    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onMainThreadEvent(MainEvent mainEvent) {
        if (mainEvent.getCode() == MainEvent.DO_SCAN_BLUETOOTH) {
            boolean isScanning = (boolean) mainEvent.getValue();
            if (isScanning) {
                BleManager.getInstance().cancelScan();
            } else {
                scan();
            }
        } else if (mainEvent.getCode() == MainEvent.DO_CONNECT_BLUETOOTH) {
            BleDevice device = (BleDevice) mainEvent.getValue();
            doConnectBluetooth(device);
        } else if (mainEvent.getCode() == MainEvent.DO_SEND_DATA) {
            OrderBean orderBean = (OrderBean) mainEvent.getValue();
            this.currentAction = orderBean.getAction();
            String order = orderBean.getOrder();
            if (mDevice != null) {
                writeData2XiaWeiJi(order);
            }
        }
    }

    //当前步骤
    private String currentAction = null;

    public void scan() {
        BleScanRuleConfig scanRuleConfig = new BleScanRuleConfig.Builder()
                .setScanTimeOut(10000)
                .build();

        if (BleManager.getInstance().getScanSate() == BleScanState.STATE_SCANNING) {
            BleManager.getInstance().cancelScan();
        }
        BleManager.getInstance().initScanRule(scanRuleConfig);
        BleManager.getInstance().scan(new BleScanCallback() {
            @Override
            public void onScanFinished(List<BleDevice> scanResultList) {
                Log.e("lmsg", "--scan  onScanFinished");
                for (BleDevice device : scanResultList) {
                    if (device.getMac().startsWith(Constant.DEFAULT_MAC)) {
                        EventBus.getDefault().post(new MainEvent<>(MainEvent.NOTIFY_BLUETOOTH_LIST, device));
                    }
                }
            }

            @Override
            public void onScanStarted(boolean success) {
                Log.e("lmsg", "--onScanStarted  success=" + success);
            }

            @Override
            public void onScanning(BleDevice bleDevice) {
                Log.e("lmsg", "--scan data=" + bleDevice.getMac());
            }
        });
    }

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    private void doConnectBluetooth(BleDevice device) {
        if (BleManager.getInstance().isConnected(device.getMac())) {
            Toast.makeText(BluetoothService.this, "设备 " + device.getMac() + " 已连接", Toast.LENGTH_LONG).show();
            return;
        }
        BleManager.getInstance().connect(device.getMac(), new BleGattCallback() {
            @Override
            public void onStartConnect() {
                Toast.makeText(BluetoothService.this, "connecting", Toast.LENGTH_SHORT).show();
            }

            @Override
            public void onConnectFail(BleDevice bleDevice, BleException exception) {
                Toast.makeText(BluetoothService.this, "connect failed", Toast.LENGTH_SHORT).show();
            }


            @Override
            public void onConnectSuccess(BleDevice bleDevice, BluetoothGatt gatt, int status) {
                Toast.makeText(BluetoothService.this, "connect success", Toast.LENGTH_SHORT).show();
                Log.e("lmsg", "--deviceMac=" + bleDevice.getMac());
                mDevice = bleDevice;

                registerNotify();
//                boolean isSuccess = gatt.requestMtu(1024);
//                Log.e("lmsg", "reset Mtu= " + isSuccess);
                EventBus.getDefault().post(new MainEvent<>(MainEvent.DO_CONNECT_BLUETOOTH_SUCCESS, bleDevice));
            }

            @Override
            public void onDisConnected(boolean isActiveDisConnected, BleDevice device, BluetoothGatt gatt, int status) {
                Toast.makeText(BluetoothService.this, "disconnect", Toast.LENGTH_SHORT).show();
            }
        });

    }

    /**
     * 注册通知
     */
    private void registerNotify() {
        notify(mDevice);
    }


    /**
     * 写收据到下位机
     *
     * @param text 指令
     */
    protected void writeData2XiaWeiJi(String text) {
        if (isHexSend) {
            text = text.replace(" ", "");
            byte[] array = Utils.hexStringToByteArray(text);
            write(array);
        } else {
            if (Utils.isAtCmd(text))
                text = text + "\r\n";
            try {
                byte[] array = text.getBytes("US-ASCII");
                write(array);
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
                System.out.println("--------------------->write text exception");
                return;
            }
        }
    }

    private BleDevice mDevice;

    public void write(byte[] message) {
        if (!BleManager.getInstance().isConnected(mDevice)) {
            Toast.makeText(this, "disconnect", Toast.LENGTH_SHORT).show();
            return;
        }

        BleManager.getInstance().write(mDevice, Constant.SERVICE_UUID, Constant.WRITE_UUID, message, new BleWriteCallback() {
            @Override
            public void onWriteSuccess(int current, int total, byte[] justWrite) {
//                Toast.makeText(BluetoothService.this, "写入成功", Toast.LENGTH_SHORT).toString();
                if (current == total) {
                    Log.e("lmsg", "wirte:HEX:" + Utils.ByteArraytoHex(justWrite) + "  (ASSCII:" + Utils.byteToASCII(justWrite) + ")");
//                    String hexString = ByteUtils.byteArrayToHexString(justWrite);
//                    Log.e("lmsg", "写入成功..." + hexString);
                }
            }

            @Override
            public void onWriteFailure(BleException exception) {
//                Toast.makeText(BluetoothService.this, "写入失败", Toast.LENGTH_SHORT).toString();
                Log.e("lmsg", "写入失败... \r\n" + "exception == " + exception.getDescription());
            }
        });
    }

    /**
     * 开启通知
     *
     * @param bleDevice
     */
    public void notify(BleDevice bleDevice) {
        BleManager.getInstance().notify(bleDevice, Constant.SERVICE_UUID, Constant.NOTIFY_UUID, new BleNotifyCallback() {
            @Override
            public void onNotifySuccess() {
                Log.e("lmsg", "==onNotifySuccess==");
            }

            @Override
            public void onNotifyFailure(BleException exception) {
                Log.e("lmsg", "==onNotifyFailure== 通知开启失败！！！ == \r\nexception== " + exception.getDescription());
            }

            @Override
            public void onCharacteristicChanged(byte[] data) {
                Log.e("lmsg", "==notifyBattery  onNotifySuccess==");
                String hexString = ByteUtils.byteArrayToHexString(data);
//                String dataString = Integer.valueOf(hexString, 16).toString();
//                Log.e("lmsg",  "--notifyBattery  onNotifySuccess  dataString=" + hexString + ",hexString=" + hexString);
                Log.e("lmsg", "read:HEX:" + Utils.ByteArraytoHex(data) + "  (ASSCII:" + Utils.byteToASCII(data) + ")");
            }
        });
    }

}
